//
//  WBSqliteTool.swift
//  WeiboTen
//
//  Created by ItHeiMa on 2017/7/19.
//  Copyright © 2017年 itHeima. All rights reserved.
//

import UIKit
import FMDB

fileprivate let cacheTime: TimeInterval = -7200

class WBSqliteTool: NSObject {
    /// 创建数据库tool的单例
    static let shared: WBSqliteTool = WBSqliteTool()
    
    var queue: FMDatabaseQueue?
    
    override init() {
        super.init()
        NotificationCenter.default.addObserver(self, selector: #selector(clearCache), name: UIApplication.didEnterBackgroundNotification, object: nil)
    }
    
    /// 打开并连接数据库
    func open (dbName: String) {
        let chacheDir = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).last
        print(chacheDir)
        let path = chacheDir! + "/" + dbName
        //如果数据库文件存在，就直接打开，如果不存在，就创建并打开
        queue = FMDatabaseQueue(path: path)
        
        //如果打开并连接数据库成功，就创建表
        if let _ = queue {
            createTable()
        }
    }
    
    /// 创建表
    func createTable () {
        let path = Bundle.main.path(forResource: "status.sql", ofType: nil)!
        //如果方法后，有throw，就代表这个方法可能抛出异常，必须处理异常，使用try
        //try，可以使用try? 或者 try!
        let sql = try! String(contentsOfFile: path)
        
        //在队列中调用FMDB对象（db）
        queue?.inDatabase({ (db) in
            //执行创建表的sql语句
            if db.executeUpdate(sql, withArgumentsIn: []) {
                print("创建表成功")
            } else {
                print("创建表失败")
            }
        })
    }
    
    /// 清理缓存
    @objc func clearCache() {
        //当前时前减一百秒，比一百秒更早的数据即为过期过期数气据
        let date = Date(timeInterval: cacheTime, since: Date())
        let dateStr = date.dateToTimeStr()
        
        let sql = "delete from T_Status where createTime < '\(dateStr)'"
        
        print("&&&&\(sql)")
        
        queue?.inDatabase({ (db) in
            db.executeUpdate(sql, withArgumentsIn: [])
        })
    }
    
    /// 向数据库插入微博的数据
    func insertStatus(modelArr: [WBStatusModel]) {
        for model in modelArr {
            //print(model)
            //模型转字典
//            let dic = model.dictionaryWithValues(forKeys: ["id", "created_at", "text", "source", "pic_urls", "user", "retweeted_status"])
//            
//            print("&&&&&&\(dic)")
            
            //在字典转json这个过程中， 原生的JSONSerialization类，处理过程比较粗糙，很多异常情况没有处理
            let jsonStr = model.yy_modelToJSONString()
            //datetime('now', 'localtime'),是sql语言中的一个函数，可能生成当前时间
            let sql = "INSERT INTO T_Status (statusId, userId, status, createTime) VALUES (?, ?, ?, datetime('now', 'localtime'));"
            
            //withArgumentsIn参数是 sql语句中的三个？所对应值的数组
            //事务操作，做批量数据处理时，可以显著提高效率
            //参数二，如果在插入数据的过程中，有异常，rollback可以设置是否回滚
            queue?.inTransaction({ (db, rollback) in
                if !db.executeUpdate(sql, withArgumentsIn: [model.id!, WBUserAccount.shared.uid!, jsonStr!]) {
                    //如果插入操作失败，就回滚
                    rollback.pointee = true
                }
            })
        }
    }
    
    /// 从数据库中查询缓存的微博的数据
    func queryStatus(since_id: String, max_id: String) -> [WBStatusModel] {
        var sql = "select * from T_Status "
        
        //如果since_id为0， 说明说上拉刷新
        if Int(max_id)! > 0 && Int(since_id)! == 0 {
            sql += "where statusId <= \(max_id)"
        }
        //说明做下拉刷新
        else if Int(since_id)! > 0 && Int(max_id)! == 0 {
            sql += "where statusId > \(since_id)"
        } else {
        
        }
        
        //创建一个模型的空数组
        var models: [WBStatusModel] = []
        
        //以statusId降序排序，并且每次反回20条数据
        sql += " order by statusId desc limit 20"
        print(sql)

        queue?.inDatabase({ (db) in
            if let resultSet = db.executeQuery(sql, withArgumentsIn: []) {
                
                while resultSet.next() {
                    //获取一共有几列
                    let colCount = resultSet.columnCount
                    
                    //逐列获取每个字段的数据
                    for i in 0..<colCount {
                        //获取列名,列名就是key值,  通过字段名(列名)取字段的值
                        if let colName = resultSet.columnName(for: i), let value = resultSet.object(forColumn: colName) as? String{
                            
                            if colName == "status" {
                                //把json字符串转进二进制的data
                                let data = value.data(using: .utf8)
                                //获取到模型的字典
                                let dic = try! JSONSerialization.jsonObject(with: data!, options: [])
                                //字典转模型
                                let model = WBStatusModel.yy_model(withJSON: dic)
                                //将模型塞到数组中
                                models.append(model!)
                                
                                break
                            }
                        }
                    }
                }
            }
        })
        
        return models
    }
}









